package net.xujialiang.XTestRPA.Service.Env;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import net.xujialiang.XTestRPA.Controller.TenantManager.Register;
import net.xujialiang.XTestRPA.Entity.Env.XRPAEnv;
import net.xujialiang.XTestRPA.Entity.Env.XRPAEnvTag;
import net.xujialiang.XTestRPA.Repository.Env.EnvTagRepository;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class XRPAEnvTagService {
    private static final Logger logger = LoggerFactory.getLogger(XRPAEnvTagService.class);

    @Autowired
    EnvTagRepository tagRepository;

    /**
     * 新建标签
     * @param tagName 标签名称
     * @param createAccount 创建账号
     * @param ttc 租户号
     */
    public void createEnvTag(String tagName, String createAccount, Integer mOrder, String ttc){
        UUID uuid = UUID.randomUUID();
        XRPAEnvTag entity = XRPAEnvTag.builder()
                .tagName(tagName)
                .tagID(uuid.toString())
                .createAccount(createAccount)
                .mOrder(mOrder)
                .createTime(new Timestamp(System.currentTimeMillis()))
                .ttc(ttc)
                .build();
        tagRepository.save(entity);
    }

    /**
     * 删除标签
     * @param id 标签ID
     */
    public void deleteEnvTag(int id, String ttc) throws Exception {
        Optional<XRPAEnvTag> entity = tagRepository.findById(id);
        if(entity.isEmpty()){
            throw new Exception("未查询到分组");
        }else{
            // 判断是否是该分组所在租户
            XRPAEnvTag tag = entity.get();
            String guid = tag.getTagID();
            // TODO: 删除标签之前需要判断组内是否有其他环境，需要先移除组内所有环境才能删除

            if(tag.getTtc().equals(ttc)){
                tagRepository.delete(entity.get());
            }else{
                throw new Exception("无权限操作");
            }
        }
    }

    /**
     * 更新标签名称
     * @param id 标签ID
     * @param tagName 标签名称
     * @throws Exception
     */
    public void updateEnvTag(int id, String tagName, Integer mOrder, String ttc) throws Exception {
        Optional<XRPAEnvTag> ret = tagRepository.findById(id);
        if(ret.isEmpty()){
            throw new Exception("未查询到标签");
        }else{
            XRPAEnvTag entity = ret.get();
            if(entity.getTtc().equals(ttc)){
                entity.setTagName(tagName);
                entity.setMOrder(mOrder);
                tagRepository.save(entity);
            }else{
                throw new Exception("无权限操作");
            }
        }
    }

    /**
     * 更新排序
     * @param newOrders 新的排序
     */
    public void updateEnvTagOrder(Map<Integer, Integer> newOrders, String ttc) throws Exception {
        Object[] ids = newOrders.keySet().toArray();
        Arrays.stream(ids).mapToInt(t-> (int) t);
        ArrayList<Integer> list = new ArrayList(Arrays.asList(ids));

        List<XRPAEnvTag> groups = (List<XRPAEnvTag>) tagRepository.findAllById(list);

        boolean noPermission = false;
        for (int i = 0; i < groups.size(); i++) {
            XRPAEnvTag group = groups.get(i);
            if(group.getTtc().equals(ttc)){
                Integer newOrder = newOrders.get(group.getId());
                group.setMOrder(newOrder);
            }else{
                noPermission= true;
            }
        }
        if(noPermission) {
            throw new Exception("无权限操作");
        }else{
            tagRepository.saveAll(groups);
        }

    }

    /**
     * 分页获取数据
     * @param page 页码
     * @param pageSize 每页条数
     * @return
     */
    public Map<String, Object> fetchTagsByPage(String ttc, String tagName, int page, int pageSize) {
        Sort sort = Sort.by(Sort.Direction.DESC, "mOrder", "id");
        PageRequest pr =  PageRequest.of(page,pageSize, sort);
        if(tagName.equals("")){
            tagName = null;
        }
        Page<XRPAEnvTag> pageData = tagRepository.findAllByTtcAndTagName(ttc, tagName, pr);
        Map<String, Object> ret = new LinkedHashMap<>();
        ret.put("totalPages", pageData.getTotalPages());
        ret.put("totalCount", pageData.getTotalElements());
        ret.put("page", page);
        ret.put("pageSize", pageSize);
        ret.put("list", pageData.getContent());
        return ret;
    }

    public List<XRPAEnvTag> fetchTagByTagIds(ArrayList tagIds){
        return (List<XRPAEnvTag>) tagRepository.findAllByTagIDIn(tagIds);
    }

    public void importTags(MultipartFile multipartFile, String ttc) throws IOException {
        String fileName = multipartFile.getOriginalFilename();
        // 获取后缀名
        String suffixName = fileName.substring(fileName.lastIndexOf("."));
        //先将.json文件转为字符串类型
        UUID uuid = UUID.randomUUID();
        File file = new File("./tmp/"+ uuid+".json");
        //将MultipartFile类型转换为File类型
        FileUtils.copyInputStreamToFile(multipartFile.getInputStream(),file);
        String jsonString = FileUtils.readFileToString(file, "UTF-8");
        JsonObject obj =  new Gson().fromJson(jsonString, JsonObject.class);
        JsonArray tagsJsonArray = (JsonArray) obj.get("Tags");
        Type listType = new TypeToken<ArrayList<XRPAEnvTag>>(){}.getType();
        List<XRPAEnvTag> tags = new Gson().fromJson(tagsJsonArray, listType);
        for (XRPAEnvTag tag : tags) {
            tag.setTtc(ttc);
        }
        List<String> ids = tags.stream().map(o->o.getTagID()).collect(Collectors.toList());
        List<XRPAEnvTag> existTags = tagRepository.findAllByTagIDInAndTtc(ids, ttc);
        List<String> existids = existTags.stream().map(o->o.getTagID()).collect(Collectors.toList());
        List<XRPAEnvTag> finalTags = tags.stream().filter(o-> !existids.contains(o.getTagID())).collect(Collectors.toList());
        if(finalTags.size()>0){
            tagRepository.saveAll(finalTags);
        }
    }
}
